#!/bin/bash

#########################################################################################
#
#  Copyright (c) 2015 arakasi72 (https://github.com/arakasi72)
#
#  --> Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
#
#########################################################################################


forceyes=1
headless=1
selfsign=1

#function to check if string is valid format for an ip address
valid_ip()
{
local ip=${1:-1.2.3.4}
local i
if expr "$ip" : '[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' >/dev/null; then
  for i in 1 2 3 4; do
    if [ $(echo "$ip" | cut -d. -f$i) -gt 255 ]; then
      return 1
    fi
  done
  return 0
else
  return 1
fi
}

# function to ask user for y/n response
ask_user(){
local answer
while true
  do
    read answer
    case $answer in [Yy]* ) return 0 ;;
                    [Nn]* ) return 1 ;;
                        * ) echo "Enter y or n";;
    esac
  done
}

# function to generate the ssl certificates
generate_certificate() {
echo -n "Generating https/ssl certificates"

openssl req -x509 -nodes -days 3650 -subj /CN=$serverip -config /etc/ssl/ruweb.cnf -newkey rsa:2048 -keyout /etc/ssl/private/ruweb.key -out /etc/ssl/ruweb.crt > /dev/null 2>&1

echo ": done"

if [ -f /etc/vsftpd.conf ]; then
  sed -i '/^\(\s\|#\)*rsa_private_key_file/ c\rsa_private_key_file=\/etc\/ssl\/private\/ruweb\.key' /etc/vsftpd.conf
  sed -i '/^\(\s\|#\)*rsa_cert_file/ c\rsa_cert_file=\/etc\/ssl\/ruweb\.crt' /etc/vsftpd.conf
  service vsftpd restart >/dev/null 2>&1
fi

if [ -f /etc/nginx/sites-available/default ]; then
  sed -i '/ssl_certificate / c\        ssl_certificate \/etc\/ssl\/ruweb\.crt;' /etc/nginx/sites-available/default
  sed -i '/ssl_certificate_key/ c\        ssl_certificate_key \/etc\/ssl\/private\/ruweb\.key;' /etc/nginx/sites-available/default
  service nginx restart >/dev/null 2>&1
fi
}

#check it is being run as root
if [ "$(id -u)" != "0" ]; then
  echo "Must be run from root or using sudo" && exit 1
fi

# options -y and -d take away the user interaction so can be called from another script
# option -y will force the creation of new certificates
# option -d will not unless it determines they are needed
while getopts ":yds" optname
  do
    case $optname in
      "y" ) forceyes=0 ;;
      "d" ) headless=0 ;;
      "s" ) selfsign=0 ;;
        * ) echo "-y, -d, and -s only options allowed" && exit ;;
    esac
  done

shift $(( $OPTIND - 1 ))

if [ $forceyes = 0 ] && [ $headless = 0 ]; then
  echo "Cannot run with both options -y and -d"
  exit
fi

if [ $# -gt 0 ]; then
  echo "No arguments allowed"
  exit
fi

if [ -z $serverip ]; then
  serverip=$(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}')
elif ! valid_ip $serverip; then
  echo "$serverip is not a valid IP address"
  serverip=$(ip route get 8.8.8.8 | awk 'NR==1 {print $NF}')
  echo "will use $serverip instead"
fi

serverdn=$(perl -MSocket -le "print((gethostbyaddr(inet_aton('$serverip'), AF_INET))[0])")

echo "IP: $serverip"
echo "DN: $serverdn"

if [ $forceyes = 1 ] && [ $headless = 1 ]; then
  echo -n "Continue y/n? "
  if ! ask_user; then
    exit
  fi
fi

if [ -z "$(grep -s $serverip$ /etc/ssl/ruweb.cnf)" ]; then
  cp /etc/ssl/openssl.cnf /etc/ssl/ruweb.cnf
  echo >> /etc/ssl/ruweb.cnf
  echo "[ v3_ca ]" >> /etc/ssl/ruweb.cnf
  echo "subjectAltName = @alt_names" >> /etc/ssl/ruweb.cnf
  echo >> /etc/ssl/ruweb.cnf
  echo "[ alt_names ]" >> /etc/ssl/ruweb.cnf
  echo "IP.1 = $serverip" >> /etc/ssl/ruweb.cnf
  if [ ! -z "$serverdn" ]; then
    echo "DNS.1 = $serverdn" >> /etc/ssl/ruweb.cnf
  fi
  echo >> /etc/ssl/ruweb.cnf
  generate_certificate

elif [ ! -f /etc/ssl/ruweb.crt ] || [ ! -f /etc/ssl/private/ruweb.key ]; then
 generate_certificate

elif [ ! -z "$serverdn" ] && [ -z "$(grep -s $serverdn /etc/ssl/ruweb.cnf)" ]; then
  dnno=1
  until [ -z "$(grep "DNS.$dnno" /etc/ssl/ruweb.cnf)" ]
    do
      dnno=$(( $dnno + 1 ))
    done
  if [ $dnno = 1 ]; then
    sed -i "/\[ alt_names \]/ aDNS.$dnno = $serverdn" /etc/ssl/ruweb.cnf
  else
     sed  -i "/DNS.$(( $dnno - 1 ))/ aDNS.$dnno = $serverdn" /etc/ssl/ruweb.cnf
  fi
  generate_certificate

elif ! openssl x509 -checkend 15768000 -noout -in /etc/ssl/ruweb.crt; then
  generate_certificate

elif [ $forceyes = 0 ]; then
  generate_certificate

elif [ $headless = 1 ]; then
  echo -n "Certificates look ok, sure you want to generate new ones y/n? "
  if ask_user ; then
    generate_certificate
  fi

else
echo "Use existing certificates"
fi
